package org.mao.forum.service.impl;

import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.mao.base.BaseServiceImpl;
import org.mao.forum.dao.ForumTaskDao;
import org.mao.forum.dao.ForumTaskLogDao;
import org.mao.forum.entity.ForumTask;
import org.mao.forum.entity.ForumTaskLog;
import org.mao.forum.enums.ForumTaskEnum;
import org.mao.forum.service.ForumTaskService;
import org.mao.quartz.QuartzTaskSchedule;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Lists;

@Service
public class ForumTaskServiceImpl extends BaseServiceImpl<ForumTask> implements ForumTaskService {

	private static Logger logger = Logger.getLogger(ForumTaskServiceImpl.class);

	@Autowired
	private ForumTaskDao forumTaskDao;

	@Autowired
	private ForumTaskLogDao forumTaskLogDao;

	@Autowired
	private QuartzTaskSchedule quartzTaskSchedule;

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void insert(ForumTask forumTask) throws Exception {
		forumTaskDao.insert(forumTask);
		ForumTaskLog log = new ForumTaskLog();
		BeanUtils.copyProperties(forumTask, log);
		log.setTaskId(forumTask.getId());
		forumTaskLogDao.insert(log);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int update(ForumTask forumTask) throws Exception {
		int count = forumTaskDao.update(forumTask);
		ForumTaskLog log = new ForumTaskLog();
		BeanUtils.copyProperties(forumTask, log);
		log.setTaskId(forumTask.getId());
		log.setCreateTime(forumTask.getUpdateTime());
		log.setCreateBy(forumTask.getUpdateBy());
		forumTaskLogDao.insert(log);
		return count;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public List<ForumTask> queryAvailableTask() {
		Date now = new Date();
		List<Integer> taskIdList = Lists.newArrayList(QuartzTaskSchedule.forumTaskUniqueList.keySet());
		List<ForumTask> forumTaskList = forumTaskDao.queryAvailableTask(taskIdList);
		for (ForumTask forumTask : forumTaskList) {
			// 一个任务必须有起始时间，执行类型，周期性执行的还必须有执行间隔时间
			if (forumTask.getStartTime() == null || forumTask.getType() == null) {
				logger.warn("Task[id=" + forumTask.getId() + "] has no startTime or type, can not be execute!");
				continue;
			}
			if (ForumTaskEnum.ForumTaskFrequencyEnum.INTELVAL.equals(forumTask.getType())) {
				if (forumTask.getEndTime() == null || forumTask.getPeriod() == null) {
					logger.warn("Task[id=" + forumTask.getId() + "] has no endTime or period when type is intelval, can not be execute!");
					continue;
				}
			}
			if (now.before(forumTask.getStartTime())) {
				// 创建一个未来将要执行的任务
				if (ForumTaskEnum.ForumTaskFrequencyEnum.ONCE.equals(forumTask.getType())) {
					quartzTaskSchedule.createSchedule(forumTask.getId(), forumTask.getStartTime(), null);
				} else if (ForumTaskEnum.ForumTaskFrequencyEnum.INTELVAL.equals(forumTask.getType())) {
					quartzTaskSchedule.createSchedule(forumTask.getId(), forumTask.getStartTime(), forumTask.getPeriod());
				}
			} else if (!now.before(forumTask.getStartTime()) && (forumTask.getEndTime() == null || now.before(forumTask.getEndTime()))) {
				// 立即创建一个任务
				if (ForumTaskEnum.ForumTaskFrequencyEnum.ONCE.equals(forumTask.getType())) {
					quartzTaskSchedule.createSchedule(forumTask.getId(), null, null);
				} else if (ForumTaskEnum.ForumTaskFrequencyEnum.INTELVAL.equals(forumTask.getType())) {
					quartzTaskSchedule.createSchedule(forumTask.getId(), null, forumTask.getPeriod());
				}
			} else {
				// 任务已过时，更新为执行完毕
				try {
					forumTask.setStatus(ForumTaskEnum.ForumTaskStatusEnum.OVER.getStatus());
					forumTask.setUpdateTime(now);
					this.update(forumTask);
				} catch (Exception e) {
					logger.error("", e);
				}
			}
		}
		return forumTaskList;
	}
}
